package sk.naive.talker;

import sk.naive.talker.util.*;
import sk.naive.talker.server.*;
import sk.naive.talker.server.Talker;
import sk.naive.talker.persistence.*;

import java.util.logging.*;
import java.rmi.registry.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;

/**
 *
 * @author <a href="mailto:virgo@naive.deepblue.sk">Richard "Virgo" Richter</a>
 * @version $Revision: 1.36 $ $Date: 2005/02/21 18:39:14 $
 */
public class Main {
	private static Logger logger = Logger.getLogger("nt.main");

	private static int registryPort;
	private static String registryHost;
	private static Registry registry;
	private static Thread shutdownHook;
	private static RemoteTalker talkerServer;
	private static Configuration configuration;

	public static Configuration getConfiguration() {
		return configuration;
	}

	public static void init(String confFile) throws TalkerConfigurationException {
		configuration = new Configuration(confFile);
	}

	public static RemoteTalker getServer()
		throws RemoteException,
		AccessException,
		NotBoundException
	{
		return (RemoteTalker) registry.lookup(RemoteTalker.NAME);
	}

	public static void initRegistry(String host, int port) throws RemoteException {
		registryHost = host;
		registryPort = port;
		registry = LocateRegistry.getRegistry(registryHost, registryPort);
		logger.config("Registry found: " + registryHost + ":" + registryPort);
	}

	public static void shutdownServices()
		throws RemoteException,
		NotBoundException,
		AccessException
	{
		Runtime.getRuntime().removeShutdownHook(shutdownHook);
		UnicastRemoteObject.unexportObject(talkerServer, true);
		registry.unbind(RemoteTalker.NAME);
	}


	private static void createRegistry()
		throws RemoteException
	{
		registry = LocateRegistry.createRegistry(registryPort);
		logger.config("Registry created...");
	}

	/** Inicializacia celeho programu talkera. */
	public static void main(String[] args) {
		try {
			String confFile = System.getProperty("talker.config.file.name");
			if (confFile == null) {
				confFile = "talker.conf";
			}
			init(confFile);

			DbTransaction.init(new DbConnectionPool.DefaultDbConnectionPool(
				getConfiguration().get("db.drivers", ""),
				getConfiguration().get("db.url"))
			);
			DbLayer db = new DbLayer();
			Integer talkerId = db.objectId(DbLayer.OBJECT_TYPE_TALKER, Consts.TPROP_NAME, Consts.TALKER_NAME);
			if (talkerId == null) {
				talkerId = db.create(DbLayer.OBJECT_TYPE_TALKER);
				db.storeProperty(talkerId, Consts.TPROP_NAME, Consts.TALKER_NAME);
				db.storeProperty(talkerId, Consts.TPROP_IDLE_TRESHOLD, "10");
				db.storeProperty(talkerId, Consts.TPROP_IDLE_BASE, "5");
				logger.info("Talker object in database created with id=" + talkerId + ".");
			}

			final Talker talker = new Talker(talkerId,
				new PropertyConfiguration("sk/naive/talker/server/PropertyResources"),
				new UserFactory("sk/naive/talker/server/UserPropertyResources"),
				new BoardFactory("sk/naive/talker/server/BoardPropertyResources")
			);
			talkerServer = new TalkerServer(talker);
			shutdownHook = new Thread() {
				public void run() {
					try {
						talker.shutdown();
					} catch (RemoteException e) {
						Utils.unexpectedExceptionWarning(e);
					}
				}
			};
			Runtime.getRuntime().addShutdownHook(shutdownHook);
			logger.log(Level.INFO, "Talker object created... {0}", new Object[] {talker});

			registryPort = configuration.getInt("registry.port", 4450);
			registryHost = configuration.get("registry.host", "localhost");
			logger.config("Registry configured: " + registryHost + ":" + registryPort);
			createRegistry();
			registry.bind(RemoteTalker.NAME, talkerServer);
			logger.info("Talker registred at RMI registry...");

			new Thread(new sk.naive.talker.tcpadapter.TCPAdapter("local4444")).start();
			logger.info("Adapter object running...");
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}
}
